/*
 * Project: Preditor2
 * File:    MainFrame.java
 * Created: Sep 22, 2004
 * By:      critchie
 * 
 * (C) 2004 Ontira Communications Inc.
 */
package com.googlecode.ddlutilstool.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyVetoException;

import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JSplitPane;

import org.apache.log4j.Logger;
import org.apache.log4j.Priority;

import com.googlecode.ddlutilstool.common.GuiNameAccessor;
import com.googlecode.ddlutilstool.kernel.GuiManager;

/**
 * <p>This is the main frame of the window.<p>
 * <p>It places the EditorDesktop, Profile list
 * and Logging window into the frame, and fills
 * out the main menu.</p>
 */
@SuppressWarnings("serial")
public class MainFrame extends JFrame {
	
	private static final Logger mLog = Logger.getLogger(MainFrame.class);

	private final static int DEFAULT_WINDOW_WIDTH = 900;
	private final static int DEFAULT_WINDOW_HEIGHT = 640;
	
	private GuiNameAccessor mGuiAccessor;
	
	private EditorDesktop mEditorDesktop;
	private ProfilePanel mProfilePanel;
	private LogPanel mLogPanel;
	private JMenu mWindowsMenu;
	
	/**
	 * @param title
	 * @throws java.awt.HeadlessException
	 */
	public MainFrame(ProfilePanel pProfilePanel,EditorDesktop pEditorDesktop, LogPanel pLogPanel) throws HeadlessException {
		super();
		mGuiAccessor = new GuiNameAccessor();
		setTitle(mGuiAccessor.getString("label.application"));
		
		setIconImage(mGuiAccessor.getImage("img.application.icon"));
		addWindowListener(new MainFrameWindowListener());

		getContentPane().setLayout(new BorderLayout());

		mProfilePanel = pProfilePanel;
		mEditorDesktop = pEditorDesktop;
		mLogPanel = pLogPanel;
		
		//add the profile and editor panels, with a adjustable split pane,
		JSplitPane rightLeftSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, mProfilePanel, mEditorDesktop);
		rightLeftSplitPane.setOneTouchExpandable(true);
		rightLeftSplitPane.setDividerLocation(250);
		Dimension minimumSize = new Dimension(100, 50);
		mProfilePanel.setMinimumSize(minimumSize);
		mEditorDesktop.setMinimumSize(minimumSize);
		getContentPane().add(rightLeftSplitPane, BorderLayout.CENTER);
		
		//add the logging panel along the botton.
		getContentPane().add(mLogPanel,BorderLayout.SOUTH);
		
		//add the menu
		JMenuBar menuBar = new JMenuBar();
		JMenu menu;
		JMenuItem item;
	
		//Create the preset file menu
		menu = new JMenu(mGuiAccessor.getString("menu.file"));
		menu.setMnemonic(KeyEvent.VK_F);
		menuBar.add(menu);

		menu.add(mEditorDesktop.getNewAction());		
		menu.add(mEditorDesktop.getOpenAction());		
		menu.add(mEditorDesktop.getSaveAction());		
		menu.add(mEditorDesktop.getSaveAsAction());		
		menu.add(mEditorDesktop.getCloseAction());		
		
        menu.addSeparator();
		item = new JMenuItem(mGuiAccessor.getString("menu.file.quit"),
				mGuiAccessor.getImageIcon("menu.file.quit.button"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				GuiManager.getInstance().teardown();
			}
		});
		menu.add(item);

	
        menu = new JMenu(mGuiAccessor.getString("menu.edit"));
		menu.setMnemonic(KeyEvent.VK_E);
		menuBar.add(menu);
		
        //Undo and redo are actions of our own creation.
        menu.add(mEditorDesktop.getUndoAction());
        menu.add(mEditorDesktop.getRedoAction());
        menu.addSeparator();

        //These actions come from the default editor kit.
        //Get the ones we want and stick them in the menu.
        menu.add(mEditorDesktop.getCutAction());
        menu.add(mEditorDesktop.getCopyAction());
        menu.add(mEditorDesktop.getPasteAction());
        
		//Create the preset profile menu
		menu = new JMenu(mGuiAccessor.getString("menu.profile"));
		menu.setMnemonic(KeyEvent.VK_P);
		menuBar.add(menu);

		item = new JMenuItem(mGuiAccessor.getString("menu.profile.add"),
				mGuiAccessor.getImageIcon("menu.profile.add.button"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				GuiManager.getInstance().addProfile();
			}
		});
		menu.add(item);
		
		item = new JMenuItem(mGuiAccessor.getString("menu.profile.edit"),
				mGuiAccessor.getImageIcon("menu.profile.edit.button"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				GuiManager.getInstance().editProfile();
			}
		});
		menu.add(item);
		
		item = new JMenuItem(mGuiAccessor.getString("menu.profile.delete"),
				mGuiAccessor.getImageIcon("menu.profile.delete.button"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				GuiManager.getInstance().deleteProfile();
			}
		});
		menu.add(item);
		
		menu.addSeparator();
		item = new JMenuItem(mGuiAccessor.getString("menu.profile.drivers"),
				mGuiAccessor.getImageIcon("menu.profile.drivers.button"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				GuiManager.getInstance().editDrivers();
			}
		});
		menu.add(item);
		
		
		//Create the execute menu
		menu = new JMenu(mGuiAccessor.getString("menu.execute"));
		menu.setMnemonic(KeyEvent.VK_X);
		menuBar.add(menu);

		item = new JMenuItem(mGuiAccessor.getString("menu.execute.sddltodb"),
				mGuiAccessor.getImageIcon("menu.execute.sddltodb.button"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				GuiManager.getInstance().startSchemaDDLToDatabase();
			}
		});
		menu.add(item);
		
		item = new JMenuItem(mGuiAccessor.getString("menu.execute.sddltofile"),
				mGuiAccessor.getImageIcon("menu.execute.sddltofile.button"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				GuiManager.getInstance().startSchemaDDLToFile();
			}
		});
		menu.add(item);
		
		item = new JMenuItem(mGuiAccessor.getString("menu.execute.scddltosql"),
				mGuiAccessor.getImageIcon("menu.execute.scddltosql.button"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				GuiManager.getInstance().startCreateSchemaDDLToSQL();
			}
		});
		menu.add(item);
		
		item = new JMenuItem(mGuiAccessor.getString("menu.execute.saddltosql"),
				mGuiAccessor.getImageIcon("menu.execute.saddltosql.button"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				GuiManager.getInstance().startAlterSchemaDDLToSQL();
			}
		});
		menu.add(item);
		
		item = new JMenuItem(mGuiAccessor.getString("menu.execute.dddltodb"),
				mGuiAccessor.getImageIcon("menu.execute.dddltodb.button"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				GuiManager.getInstance().startDataDDLToDatabase();
			}
		});
		menu.add(item);
		
		item = new JMenuItem(mGuiAccessor.getString("menu.execute.dddltofile"),
				mGuiAccessor.getImageIcon("menu.execute.dddltofile.button"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				GuiManager.getInstance().startDataDDLToFile();
			}
		});
		menu.add(item);

		item = new JMenuItem(mGuiAccessor.getString("menu.execute.dddltosql"),
				mGuiAccessor.getImageIcon("menu.execute.dddltosql.button"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				GuiManager.getInstance().startDataDDLToSQL();
			}
		});
		menu.add(item);

		//Create the windows menu
		mWindowsMenu = new JMenu(mGuiAccessor.getString("menu.windows"));
		mWindowsMenu.setMnemonic(KeyEvent.VK_W);
		menuBar.add(mWindowsMenu);

		updateWindowsMenu();
		
		setJMenuBar(menuBar);
		
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

		mEditorDesktop.setFrame(this);
		setSize(DEFAULT_WINDOW_WIDTH,DEFAULT_WINDOW_HEIGHT);
	}


	/**
	 * Called when DDL is being executed, it disables
	 * the editor windows, the profile list and
	 * the menu options.
	 */
	public void disableForExecution() {
		mEditorDesktop.setEnabled(false);
		mProfilePanel.setEnabled(false);
		JMenuBar menuBar = getJMenuBar();
		for (int x=0; x<menuBar.getMenuCount(); x++) {
			JMenu menu = menuBar.getMenu(x);
			menu.setEnabled(false);
		}
	}
	
	/**
	 * Called after the DDL is executed, it reenables
	 * the editor windows, the profile list and
	 * the menu options.
	 */
	public void reenableAfterExecution() {
		mEditorDesktop.setEnabled(true);
		mProfilePanel.setEnabled(true);
		JMenuBar menuBar = getJMenuBar();
		for (int x=0; x<menuBar.getMenuCount(); x++) {
			JMenu menu = menuBar.getMenu(x);
			menu.setEnabled(true);
		}
		
	}
	
	/**
	 * Called by the Editors, it will update the Window
	 * menu.  This menu contains the list of
	 * editor windows.
	 */
	public void updateWindowsMenu() {
		mWindowsMenu.removeAll();
		JInternalFrame[] frames = mEditorDesktop.getAllFrames();
		
		for (JInternalFrame frame : frames) {
			mWindowsMenu.add(new WindowMenuAction(frame));
		}
	}

	
	/**
	 * This class listens for the window dying, and logs out the monitor
	 * if it does.
	 */
	public class MainFrameWindowListener extends WindowAdapter
	{
		/**
		 * Called when a window is closed
		 *
		 * @param	e		the window's event object
		 */
		public void windowClosing(WindowEvent pEvent)
		{
		    GuiManager.getInstance().teardown();
		}
	}
	class WindowMenuAction extends AbstractAction {
		private JInternalFrame mFrame;
        public WindowMenuAction(JInternalFrame frame) {
            super(frame.getTitle(),mGuiAccessor.getImageIcon("menu.windows.button"));
            mFrame = frame;
            setEnabled(true);
        }

        public void actionPerformed(ActionEvent e) {
        	try {
				mFrame.setSelected(true);
			} 
        	catch (PropertyVetoException e1) {
				if (mLog.isEnabledFor(Priority.ERROR)) mLog.error(e1);
			}
        }

    }
}
